﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.IO;

namespace ChestPainCenterSystem.Utils
{
	/// <summary>
	/// 字符串操作类
	/// </summary>
	public class StringHelper {
		#region 使用指定分割符，扩充字符串
		/// <summary>
		/// 使用指定分割符，扩充字符串
		/// </summary>
		/// <param name="sb">sb</param>
		/// <param name="append">要增加的字符串</param>
		/// <param name="split">分隔符，默认不传为英文逗号</param>
		public static void AppendString(StringBuilder sb, string append, string split = ",") {
			if (sb.Length == 0) {
				sb.Append(append);
			}
			else {
				sb.Append(split);
				sb.Append(append);
			}
		}
		#endregion
		#region 从Base64字符串中还原字符串
		/// <summary>
		/// 从Base64字符串中还原字符串
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public static string Base64StringDecode(string input) {
			byte[] bytes = Convert.FromBase64String(input);
			return Encoding.UTF8.GetString(bytes);
		}
		#endregion
		#region 将字符串保存为Base64编码序列
		/// <summary>
		/// 将字符串保存为Base64编码序列
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public static string Base64StringEncode(string input) {
			return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
		}
		#endregion
		#region 检查一个数组中所有的元素是否有包含于指定字符串的元素
		/// <summary>
		/// 检查一个数组中所有的元素是否有包含于指定字符串的元素
		/// </summary>
		/// <param name="checkStr">存储数据的字串</param>
		/// <param name="findStr">要查找的字符串</param>
		/// <param name="split">数组的分隔符 默认不传为英文逗号</param>
		/// <returns></returns>
		public static bool FoundCharInArr(string checkStr, string findStr, string split = ",") {
			bool flag = false;
			if (string.IsNullOrEmpty(checkStr)) {
				return false;
			}
			if (checkStr.IndexOf(split) != -1) {
				if (findStr.IndexOf(split) != -1) {
					string[] strArray = checkStr.Split(new char[] { Convert.ToChar(split) });
					string[] strArray2 = findStr.Split(new char[] { Convert.ToChar(split) });
					foreach (string str in strArray) {
						foreach (string str2 in strArray2) {
							if (string.Compare(str, str2) == 0) {
								flag = true;
								break;
							}
						}
						if (flag) {
							return flag;
						}
					}
					return flag;
				}
				foreach (string str3 in checkStr.Split(new char[] { Convert.ToChar(split) })) {
					if (string.Compare(str3, findStr) == 0) {
						return true;
					}
				}
				return flag;
			}
			if (string.Compare(checkStr, findStr) == 0) {
				flag = true;
			}
			return flag;
		}
		/// <summary>
		/// 检查一个数组中所有的元素是否有包含于指定字符串的元素
		/// </summary>
		/// <param name="arr">存储数据的字串</param>
		/// <param name="toFind">要查找的字符串</param>
		/// <param name="separator">数组的分隔符</param>
		/// <returns></returns>
		public static bool FoundStringInArr(string arr, string toFind, char separator) {
			if (arr.IndexOf(separator) >= 0) {
				string[] arrTemp = arr.Split(separator);
				for (int i = 0; i < arrTemp.Length; i++) {
					if ((toFind.ToLower().IndexOf(arrTemp[i].ToLower()) >= 0) && (arrTemp[i].ToLower() != ""))
						return true;
				}
			}
			else {
				if ((toFind.ToLower().IndexOf(arr.ToLower())) >= 0 && (arr.ToLower() != ""))
					return true;
			}
			return false;
		}
		#endregion
		#region 分割字符串
		/// <summary>
		/// 分割字符串
		/// </summary>
		public static string[] SplitString(string strContent, string strSplit) {
			int i = strContent.IndexOf(strSplit);
			if (strContent.IndexOf(strSplit) < 0) {
				string[] tmp = { strContent };
				return tmp;
			}
			return Regex.Split(strContent, @strSplit.Replace(".", @"\.").Replace("|", @"\|").Replace("$", @"\$").Replace("{", @"\{").Replace("}", @"\}").Replace("^", @"\^").Replace("(", @"\(").Replace(")", @"\)").Replace("]", @"\]").Replace("[", @"\[").Replace("*", @"\*").Replace("+", @"\+").Replace("?", @"\?"));
		}
		#endregion
		#region MD5加密 不可逆
		/// <summary>
		/// MD5加密 不可逆
		/// </summary>
		/// <param name="str">原始字符串</param>
		/// <returns>结果</returns>
		public static string Encrypt(string str) {
			string result = MD5(str).ToUpper();
			result = result.Replace("1", "").Replace("3", "").Replace("5", "").Replace("7", "").Replace("9", "");
			return result;
		}
		#endregion
		#region 计算MD5散列
		/// <summary>
		/// 计算MD5散列
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static string MD5(string str) {
			byte[] b = Encoding.UTF8.GetBytes(str);
			b = new MD5CryptoServiceProvider().ComputeHash(b);
			string ret = "";
			for (int i = 0; i < b.Length; i++)
				ret += b[i].ToString("x").PadLeft(2, '0');
			return ret;
		}
		#endregion
		#region 自定义的替换字符串函数
		/// <summary>
		/// 自定义的替换字符串函数
		/// </summary>
		/// <param name="sourceStr">原字符串</param>
		/// <param name="searchStr">需要被替换的字符串</param>
		/// <param name="replaceStr">替换字符串</param>
		/// <param name="isCaseInsensetive">true 为指定不区分大小写的匹配。</param>
		/// <returns></returns>
		public static string ReplaceString(string sourceStr, string searchStr, string replaceStr, bool isCaseInsensetive) {
			return Regex.Replace(sourceStr, Regex.Escape(searchStr), replaceStr, isCaseInsensetive ? RegexOptions.IgnoreCase : RegexOptions.None);
		}
		#endregion
		#region 计算哈散列
		/// <summary>
		/// 计算哈散列
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public static string SHA1(string input) {
			using (SHA1CryptoServiceProvider provider = new SHA1CryptoServiceProvider()) {
				return BitConverter.ToString(provider.ComputeHash(Encoding.UTF8.GetBytes(input))).Replace("-", "").ToLower();
			}
		}
		#endregion
		#region 过滤使用使用尖括号括起来的标签,但会保留标签中间的内容。eg. <tr>11</tr>,执行为11
		/// <summary>
		/// 过滤使用使用尖括号括起来的标签,但会保留标签中间的内容。eg. <tr>11</tr>,执行为11
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public static string StripTags(string input) {
			Regex regex = new Regex("<([^<]|\n)+?>");
			return regex.Replace(input, "");
		}
		#endregion
		#region 返回指定长度的子字符串
		/// <summary>
		/// 返回指定长度的子字符串
		/// </summary>
		/// <param name="sourceString">源字符</param>
		/// <param name="length">长度</param>
		/// <param name="substitute">省略后替代的字符如:"..."等 默认不传为空</param>
		/// <param name="chineseTo2">为true时，一个汉字的长度为2；反之为1 默认不传为true</param>
		/// <returns>字符串</returns>
		public static string SubString(string sourceString, int length, string substitute = "", bool chineseTo2 = true) {
			if (Encoding.Default.GetBytes(sourceString).Length <= length) {
				return sourceString;
			}
			ASCIIEncoding encoding = new ASCIIEncoding();
			length -= Encoding.Default.GetBytes(substitute).Length;
			int num = 0;
			StringBuilder builder = new StringBuilder();
			byte[] bytes = encoding.GetBytes(sourceString);
			for (int i = 0; i < bytes.Length; i++) {
				if (bytes[i] == 0x3f && chineseTo2) {
					num += 2;
				}
				else {
					num++;
				}
				if (num > length) {
					break;
				}
				builder.Append(sourceString.Substring(i, 1));
			}
			builder.Append(substitute);
			return builder.ToString();
		}
		#endregion
		#region 返回字串长度,中文字符为计2,其他计1
		/// <summary>
		/// 返回字串长度,中文字符为计2,其他计1
		/// 使用ASCII将字符串转化为字节数组时(byte[]),数组长度跟字符串长度相同
		/// 非中文字符取其ASCII码,中文ASCII码为63即?(十六进制为0x3F)
		/// </summary>
		/// <returns></returns>
		public static int GetStringLength(string str) {
			return Encoding.Default.GetBytes(str).Length;
		}
		#endregion
		#region 去除字串两边的空格,当字串为Null Or Empty时,返回 String.Empty
		/// <summary>
		/// 去除字串两边的空格,当字串为Null Or Empty时,返回 String.Empty
		/// </summary>
		/// <param name="returnStr"></param>
		/// <returns></returns>
		public static string Trim(string returnStr) {
			if (!string.IsNullOrEmpty(returnStr)) {
				return returnStr.Trim();
			}
			return string.Empty;
		}
		#endregion
		#region 替换回车换行符为html换行符
		/// <summary>
		/// 替换回车换行符为html换行符
		/// </summary>
		public static string StrFormat(string str) {
			string str2;

			if (str == null) {
				str2 = "";
			}
			else {
				str = str.Replace("\r\n", "<br />");
				str = str.Replace("\n", "<br />");
				str2 = str;
			}
			return str2;
		}
		#endregion
		#region 在生成CSV时替换字符串中特殊字符
		/// <summary>
		/// 在生成CSV时替换字符串中特殊字符
		/// </summary>
		/// <param name="content"></param>
		/// <returns></returns>
		public static string ReplaceCSVBadString(string content) {
			if (string.IsNullOrEmpty(content))
				return string.Empty;
			return content.Replace(",", "，").Replace("\r\n", "").Replace("\n", "").Replace("\"", "“");
		}
		#endregion
		#region 过滤标签,正则匹配时使用非贪婪模式
		/// <summary>
		/// 过滤标签,正则匹配时使用非贪婪模式
		/// </summary>
		/// <param name="conStr">待处理的文本数据</param>
		/// <param name="tagName">标签名称如,html,Script等</param>
		/// <param name="fType">过滤方式,可以取(1|2|3)
		/// 1:是单个标签如img等,
		/// 2:表示配对出现的标签如div等将清除此标签以及标签内的全部文本,
		/// 3:表示也是针对配对出现的标签,但是保留标签内的内容.
		/// </param>
		/// <returns></returns>
		public static string CollectionFilter(string conStr, string tagName, int fType) {
			string input = conStr;
			switch (fType) {
				case 1:
					return Regex.Replace(input, "<" + tagName + "([^>])*>", "", RegexOptions.IgnoreCase);

				case 2:
					return Regex.Replace(input, "<" + tagName + "([^>])*>.*?</" + tagName + "([^>])*>", "", RegexOptions.IgnoreCase);

				case 3:
					return Regex.Replace(Regex.Replace(input, "<" + tagName + "([^>])*>", "", RegexOptions.IgnoreCase), "</" + tagName + "([^>])*>", "", RegexOptions.IgnoreCase);
			}
			return input;
		}
		#endregion
		#region 过滤标签
		/// <summary>
		/// 过滤标签
		/// </summary>
		/// <param name="conStr"></param>
		/// <param name="filterItem">标签项，多个用英文逗号隔开</param>
		/// <returns></returns>
		public static string FilterScript(string conStr, string filterItem) {
			filterItem = filterItem.ToLower();
			string str = conStr.Replace("\r", "{$Chr13}").Replace("\n", "{$Chr10}");
			foreach (string str2 in filterItem.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) {
				switch (str2) {
					case "body":
						str = CollectionFilter(str, str2, 3);
						break;
					case "iframe":
						str = CollectionFilter(str, str2, 3);
						break;

					case "object":
						str = CollectionFilter(str, str2, 3);
						break;

					case "script":
						str = CollectionFilter(str, str2, 3);
						break;

					case "style":
						str = CollectionFilter(str, str2, 3);
						break;

					case "div":
						str = CollectionFilter(str, str2, 3);
						break;

					case "span":
						str = CollectionFilter(str, str2, 3);
						break;

					case "table":
						str = CollectionFilter(CollectionFilter(CollectionFilter(CollectionFilter(CollectionFilter(str, str2, 3), "Tbody", 3), "Tr", 3), "Td", 3), "Th", 3);
						break;

					case "img":
						str = CollectionFilter(str, str2, 1);
						break;

					case "font":
						str = CollectionFilter(str, str2, 3);
						break;

					case "a":
						str = CollectionFilter(str, str2, 3);
						break;

					case "p":
						str = CollectionFilter(str, str2, 3);
						break;

					case "html":
						str = StripTags(str);
						break;
				}
			}
			return str.Replace("{$Chr13}", "\r").Replace("{$Chr10}", "\n");
		}
		#endregion
		#region xml编码
		/// <summary>
		/// xml编码
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static string XmlEncode(string str) {
			if (!string.IsNullOrEmpty(str)) {
				str = str.Replace("&", "&amp;");
				str = str.Replace("<", "&lt;");
				str = str.Replace(">", "&gt;");
				str = str.Replace("'", "&apos;");
				str = str.Replace("\"", "&quot;");
			}
			return str;
		}
		#endregion
		#region 过滤编辑器的危险文本
		/// <summary>
		/// 过滤编辑器的危险文本
		/// </summary>
		/// <param name="str">文本内容</param>
		/// <returns></returns>
		public static string GetEditorSafeContent(string str) {
			if (string.IsNullOrEmpty(str)) {
				return "";
			}
			else {
				str = StringHelper.FilterScript(str, "Script,Iframe,Object,Body");
				return str.Trim();
			}
		}
		#endregion
		#region 返回字串的拼音首字母序列

		/// <summary>
		/// 返回字串的拼音首字母序列(字串中的英文直接返回)
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static string GetInitial(string str) {
			StringBuilder builder = new StringBuilder();
			for (int i = 0; i < str.Length; i++) {
				builder.Append(GetOneIndex(str.Substring(i, 1)));
			}
			return builder.ToString();
		}

		private static string GetOneIndex(string testTxt) {
			if ((Convert.ToChar(testTxt) >= '\0') && (Convert.ToChar(testTxt) < 'Ā')) {
				return testTxt;
			}
			return GetGbkX(testTxt);
		}
		/// <summary>
		/// 返回字符串首字符,如果字符串首字符是汉字则返回其拼音的第一个字符(A-Z)
		/// </summary>
		/// <param name="testTxt"></param>
		/// <returns></returns>
		private static string GetGbkX(string testTxt) {
			if (testTxt.CompareTo("吖") >= 0) {
				if (testTxt.CompareTo("八") < 0) {
					return "A";
				}
				if (testTxt.CompareTo("嚓") < 0) {
					return "B";
				}
				if (testTxt.CompareTo("咑") < 0) {
					return "C";
				}
				if (testTxt.CompareTo("妸") < 0) {
					return "D";
				}
				if (testTxt.CompareTo("发") < 0) {
					return "E";
				}
				if (testTxt.CompareTo("旮") < 0) {
					return "F";
				}
				if (testTxt.CompareTo("铪") < 0) {
					return "G";
				}
				if (testTxt.CompareTo("讥") < 0) {
					return "H";
				}
				if (testTxt.CompareTo("咔") < 0) {
					return "J";
				}
				if (testTxt.CompareTo("垃") < 0) {
					return "K";
				}
				if (testTxt.CompareTo("嘸") < 0) {
					return "L";
				}
				if (testTxt.CompareTo("拏") < 0) {
					return "M";
				}
				if (testTxt.CompareTo("噢") < 0) {
					return "N";
				}
				if (testTxt.CompareTo("妑") < 0) {
					return "O";
				}
				if (testTxt.CompareTo("七") < 0) {
					return "P";
				}
				if (testTxt.CompareTo("亽") < 0) {
					return "Q";
				}
				if (testTxt.CompareTo("仨") < 0) {
					return "R";
				}
				if (testTxt.CompareTo("他") < 0) {
					return "S";
				}
				if (testTxt.CompareTo("哇") < 0) {
					return "T";
				}
				if (testTxt.CompareTo("夕") < 0) {
					return "W";
				}
				if (testTxt.CompareTo("丫") < 0) {
					return "X";
				}
				if (testTxt.CompareTo("帀") < 0) {
					return "Y";
				}
				if (testTxt.CompareTo("咗") < 0) {
					return "Z";
				}
			}
			return testTxt;
		}

		#endregion
        #region 字符串DES加密

        /// <summary>   
        /// 利用DES加密算法加密字符串（可解密）   
        /// </summary>   
        /// <param name="plaintext">被加密的字符串</param>   
        /// <param name="key">密钥（只支持8个字节的密钥）</param>   
        /// <returns>加密后的字符串</returns>   
        public static string EncryptString(string plaintext, string key)
        {
            //访问数据加密标准(DES)算法的加密服务提供程序 (CSP) 版本的包装对象   
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            des.Key = ASCIIEncoding.ASCII.GetBytes(key);　//建立加密对象的密钥和偏移量   
            des.IV = ASCIIEncoding.ASCII.GetBytes(key);　 //原文使用ASCIIEncoding.ASCII方法的GetBytes方法   

            byte[] inputByteArray = Encoding.Default.GetBytes(plaintext);//把字符串放到byte数组中   

            MemoryStream ms = new MemoryStream();//创建其支持存储区为内存的流　   
            //定义将数据流链接到加密转换的流   
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            //上面已经完成了把加密后的结果放到内存中去   
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }
        /// <summary>   
        /// 利用DES解密算法解密密文（可解密）   
        /// </summary>   
        /// <param name="ciphertext">被解密的字符串</param>   
        /// <param name="key">密钥（只支持8个字节的密钥，同前面的加密密钥相同）</param>   
        /// <returns>返回被解密的字符串</returns>   
        public static string DecryptString(string ciphertext, string key)
        {
            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                byte[] inputByteArray = new byte[ciphertext.Length / 2];
                for (int x = 0; x < ciphertext.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(ciphertext.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }

                des.Key = ASCIIEncoding.ASCII.GetBytes(key);　//建立加密对象的密钥和偏移量，此值重要，不能修改   
                des.IV = ASCIIEncoding.ASCII.GetBytes(key);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

                cs.Write(inputByteArray, 0, inputByteArray.Length);

                cs.FlushFinalBlock();

                //建立StringBuild对象，createDecrypt使用的是流对象，必须把解密后的文本变成流对象   
                StringBuilder ret = new StringBuilder();

                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            catch (Exception)
            {
                return "error";
            }
        }

        #endregion
    }
}